package com.javasm.mingming.login.service.impl;

import com.javasm.mingming.adminuser.entity.AdminUser;
import com.javasm.mingming.adminuser.service.AdminUserService;
import com.javasm.mingming.common.RandomStringGenerator;
import com.javasm.mingming.common.RedisKeys;
import com.javasm.mingming.common.exception.JavasmException;
import com.javasm.mingming.common.exception.JavasmExceptionEnum;
import com.javasm.mingming.common.utils.SmsUtil;
import com.javasm.mingming.login.entity.LoginUserDetails;
import com.javasm.mingming.login.service.LoginService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

/**
 * @author javasm
 * @version 0.1
 * @className LoginServiceImpl
 * @descriptioin:
 * @date 2025/1/11 15:24
 * @since jdk11
 */
@Service
public class LoginServiceImpl implements LoginService {

    Logger logger = LogManager.getLogger(LoginService.class);

    @Resource
    AdminUserService adminUserService;

    @Resource
    PasswordEncoder passwordEncoder;
    @Resource
    HttpSession session;
    @Resource
    RedisTemplate<String,Object> redisTemplate;
    @Override
    public void updatePassword(String uid, String password) {
        //把密码 加密成 加密字符串
        String newPassword = passwordEncoder.encode(password);
        //更新
        AdminUser adminUser = new AdminUser();
        adminUser.setUid(Long.valueOf(uid));
        adminUser.setPassword(newPassword);
        adminUserService.updateById(adminUser);
    }

    @Override
    public AdminUser jsonLogin(AdminUser adminUser) {
        //查询用户信息之前,校验 验证码是否正确
        String code = adminUser.getCode();
        Object jsonCode = session.getAttribute("json_code");
        if (StringUtils.isEmpty(code) || StringUtils.isEmpty(jsonCode)){
            throw new JavasmException(JavasmExceptionEnum.CodeNull);
        }
        if (!code.equals(jsonCode)){
            throw new JavasmException(JavasmExceptionEnum.CodeError);
        }

        //查询用户信息
        String uname = adminUser.getUsername();
        //根据用户名查询用户信息
        AdminUser adminUserData = adminUserService.getByUname(uname);
        if (adminUserData == null){
            throw new JavasmException(JavasmExceptionEnum.UserNotExist);
        }
        //校验密码是否正确
        if (!passwordEncoder.matches(adminUser.getPassword(),adminUserData.getPassword())){
            throw new JavasmException(JavasmExceptionEnum.PasswordError);
        }
        //验证通过
        SecurityContext context = SecurityContextHolder.getContext();
        LoginUserDetails loginUserDetails = new LoginUserDetails(adminUserData);
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUserDetails,loginUserDetails.getPassword(),loginUserDetails.getAuthorities());
        context.setAuthentication(authenticationToken);
        return adminUserData;
    }

    @Resource
    SmsUtil smsUtil;

    @Override
    public void sendCode(String phone) {
        //随机的字符串
        String code = RandomStringGenerator.generateRandomNumberString(4);
        logger.info("--------发送验证码到手机:"+code);
        //发送到手机上
        smsUtil.sendSms(phone,code);
        //存入Redis
        String key = String.format(RedisKeys.User_Phone_Code,phone);
        redisTemplate.opsForValue().set(key,code,10, TimeUnit.DAYS);
    }

    @Override
    public AdminUser phoneLogin(AdminUser adminUser) {
        //用户的 手机号 验证码
        String phone = adminUser.getPhone();
        String code = adminUser.getCode();
        if (StringUtils.isEmpty(phone)||StringUtils.isEmpty(code)){
            throw new JavasmException(JavasmExceptionEnum.ParameterNull);
        }
        //获取 正确的 验证码
        String key = String.format(RedisKeys.User_Phone_Code,phone);
        Object o = redisTemplate.opsForValue().get(key);
        if (o == null){
            throw new JavasmException(JavasmExceptionEnum.CodeExpr);
        }
        String realCode = (String) o;
        if (!realCode.equals(code)){
            throw new JavasmException(JavasmExceptionEnum.CodeError);
        }
        //根据 手机号 查询 用户信息
        AdminUser user = adminUserService.getByPhone(phone);
        //Security登录
        LoginUserDetails userDetails = new LoginUserDetails(user);
        Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails,phone,userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return user;
    }
}
